#pragma once

#include "math.h"
#include "Simplex2.h"
#include "IDomain2.h"
#include <vector>


class LineLoop2;

/**
 * 
 * this implements simplex decomposition by using a internal point and all of its vertieces.
 * this implements boundary traverse via simplex decomposition.
 */
class ConvexPolygonalShape2 : public ISimplexDecomposed2, public IExplicitBounded2
{
public:
	virtual ~ConvexPolygonalShape2() {}
	virtual const std::size_t countVertices() const = 0;
	virtual const Vector2 getVertex(std::size_t i) const = 0;

	virtual ISimplexIterator2* decompose(IStackAllocator& stack) const;
	virtual ILinearEdgeIterator2* boundary(IStackAllocator& stack) const;

protected:
	Simplex2* createSimplex(IStackAllocator* alloc, std::size_t startIndex, std::size_t endIndex) const;
};

//class Box2 : public ConvexPolygonalShape2, public IImplicitBoundary2
//{
//};
//

/**@todo extract @tt ConvexPolygonal (shared with triangle, box, etc...) */
class ConvexPolygon2 : public ConvexPolygonalShape2
{
public:
	ConvexPolygon2() : vertices_(), internalPoint_(), needUpdate_(false) {}

	void addVertex(const Vector2& vertex);

	virtual const std::size_t countVertices() const	{	return vertices_.size();	}
	virtual const Vector2 getVertex(std::size_t i) const	{	return vertices_[i];	}

	virtual const Vector2 internalPoint() const;
	virtual const Vector2 supportPoint(const Vector2& normal) const;

private:
	void updateInternalPoint() const;
	const Vector2 calcGravity() const;

private:
	std::vector<Vector2> vertices_;
	mutable Vector2	internalPoint_;
	mutable bool	needUpdate_;
};


//class Box2 : public ConvexPolygonalShape2
//{
//public:
//	explicit Box2(const Vector2& halfExtents);
//	virtual const Vector2 internalPoint() const	{	return Vector2(0, 0);	}
//	virtual const Vector2 supportPoint(const Vector2& normal) const;
//	virtual const std::size_t countVertices() const;
//	virtual const Vector2 getVertex(std::size_t i) const;
//private:
//	Vector2 halfExtents_;
//};